package com.ecr.hub.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.faces.application.Application;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;

import org.apache.commons.beanutils.PropertyUtils;

import com.ecr.hub.ApplicationException;

public class ManagedBeanUtils {

	/**
	 * Il s'agit de pouvoir récupérer facilement les objets FacesContext,
	 * Application, ExternalContext, VariableResolver, ainsi que les objets
	 * déclarés dans le fichier de configuration JSF (méthode getVariable()).
	 */

	// Retourne le contexte courant, c'est-à-dire, la page JSP qui sert de
	// conteneur.
	public static FacesContext getFacesContext() {
		return FacesContext.getCurrentInstance();
	}

	public static Application getApplication() {
		return getFacesContext().getApplication();
	}

	// Retourne un objet relatif à tous les éléments externes à la page courante
	// (request, response, etc..).
	public static ExternalContext getExternalContext() {
		return getFacesContext().getExternalContext();
	}

	/**
	 * Force le raffraîchissement de la page courante (ex : bouton
	 * réinitialiser...).
	 */
	public static void refreshCurrentPage() {

		FacesContext context = FacesContext.getCurrentInstance();
		String viewId = context.getViewRoot().getViewId();
		ViewHandler handler = context.getApplication().getViewHandler();
		UIViewRoot root = handler.createView(context, viewId);
		root.setViewId(viewId);
		context.setViewRoot(root);
	}

	/**
	 * Lorsque l'on utilise des composants graphiques de type sélection
	 * (<h:selectOneMenu, <h:selectManyListBox>...), il faut transformer les
	 * listes d'objets récupérés depuis la couche métier, en listes d'objets de
	 * type SelectItem pour alimenter les valeurs sélectionnables des composants
	 * graphiques
	 * 
	 * @param original
	 *            collection des objets issus de la couche métier
	 * @param labelProperty
	 *            nom de la propriété des objets métier utilisée comme libellé
	 *            dans SelectItem
	 * @param valueProperty
	 *            nom de la propriété des objets métier utilisée comme valeur
	 *            dans SelectItem
	 * @param prefix
	 *            texte à rajouter devant le label.
	 */
	public static List<SelectItem> buildSelectCollection(
			Collection<?> original, String labelProperty, String valueProperty,
			String prefix) throws ApplicationException {
		List<SelectItem> result = new ArrayList<SelectItem>();
		if (original != null) {
			try {
				for (Object obj : original) {
					String label = (String) PropertyUtils.getProperty(obj,
							labelProperty);
					Object value = PropertyUtils
							.getProperty(obj, valueProperty);

					if (null != prefix)
						label = prefix + label;
					SelectItem item = new SelectItem(value, label);
					result.add(item);
				}
			} catch (Exception e) {
				throw new ApplicationException(e);
			}
		}
		return result;
	}

	/**
	 * Méthode standard pour la céation des listes déroulantes. Pas de prefix à
	 * ajouter au label.
	 */
	public static List<SelectItem> buildSelectCollection(
			Collection<?> original, String labelProperty, String valueProperty)
			throws ApplicationException {

		return buildSelectCollection(original, labelProperty, valueProperty,
				null);
	}

	/**
	 * Méthode interne pour la récupération du chemin complet pour un fichier (
	 * chemin absolu à partir de la racine ).
	 */
	public static String getRealPath(String fileToGetRealPath) {
		return getExternalContext().getRealPath(fileToGetRealPath);
	}
}
